﻿using System;
using System.Collections.Generic;

namespace QDT.Core.Projects.LoanAlgorithm
{
    public class MonthInterestAlgorithm : AbstractLoanAlgorithm {
        public MonthInterestAlgorithm(decimal money, double rate, int month) : base(money, rate) {
            Month = month;
        }

        public MonthInterestAlgorithm(Project project):base(project) {

            Month = project.RepayTime;

        }

        #region Overrides of LoanAlgorithm

        /// <summary>
        /// 投资的月份数
        /// </summary>
        public int Month { get; private set; }

        /// <summary>
        /// 获得总的收益
        /// </summary>
        /// <returns></returns>
        public override decimal TotalInterest { get { return MonthInterest*Month; } }

        /// <summary>
        /// 计算月息
        /// </summary>
        public decimal MonthInterest { get { return Principal*(Convert.ToDecimal(Rate)/12/100); } }

        /// <summary>
        /// 获得还款模型表
        /// </summary>
        /// <returns></returns>
        public override ICollection<RepayModel> GetModelTable(DateTime startTime)
        {
            var models = new List<RepayModel>();

            for (int i = 1; i <= Month; i++) {
                var model = new RepayModel {
                                               Stage = i,
                                               Interest = MonthInterest,
                                               Principal = 0,
                                               RemainPrincipal = Principal,
                                               Ammount = MonthInterest,
                                               RemainInterest = GetRemainInterest(i),
                                               RemainAmmount = GetRemainAmmount(i),
                                               Remark = "利息",
                                               Time = ReplayTimeOfCycle(startTime, i)
                                           };

                models.Add(model);
            }

            //最后一期为偿还本金期
            int endStage = Cycle;

            models.Add(new RepayModel {
                                          Stage = endStage,
                                          Interest = 0,
                                          Principal = Principal,
                                          RemainPrincipal = 0,
                                          Ammount = Principal,
                                          RemainInterest = GetRemainInterest(endStage),
                                          RemainAmmount = GetRemainAmmount(endStage),
                                          Remark = "本金",
                                          Time = ReplayTimeOfCycle(startTime, endStage).AddDays(-1),
                                          IsLast = true
                                      });
            return models;
        }

        #endregion

        /// <summary>
        /// 获得当前类型总偿还期次
        /// </summary>
        protected virtual int Cycle { get { return Month + 1; } }

        /// <summary>
        /// 根据指定期次，获得剩余的利息
        /// </summary>
        /// <param name="stage"></param>
        /// <returns></returns>
        protected virtual decimal GetRemainInterest(int stage) {
            //如果是最后一期
            if (stage == Cycle) {
                return 0;
            }
            return TotalInterest - MonthInterest*stage;
        }

        /// <summary>
        /// 根据指定期次，获得剩余总的偿还金额
        /// </summary>
        /// <param name="stage"></param>
        /// <returns></returns>
        protected virtual decimal GetRemainAmmount(int stage) {
            if (stage == Cycle) {
                return Principal;
            }
            return TotalRepayAccount - MonthInterest*stage;
        }

        /// <summary>
        /// 按月份的形式计算每期还款时间
        /// </summary>
        /// <param name="startTime">贷款开始时间</param>
        /// <param name="stage"></param>
        /// <returns></returns>
        protected virtual DateTime ReplayTimeOfCycle(DateTime startTime, int stage) {
            //提前发放利息，有问题（2014-3-10）
            stage -= 1;

            DateTime replyTime = startTime.AddMonths(stage);

            int d = startTime.Day;

            //解决29，30，31计算下一个月出现的问题
            int endDay = DateTime.DaysInMonth(replyTime.Year, replyTime.Month);

            if (d > endDay) d = endDay;

            return new DateTime(replyTime.Year, replyTime.Month, d);
        }
    }
}